#include <stdio.h>
unsigned long long int BASE_DRAM0_ADDR = 0x0080000000;
unsigned long long int BASE_RS_ADDR    = 0x0080001000;
unsigned long long int BASE_DRAM1_ADDR = 0x00a0000000;
unsigned int    cfg_cim_wet_num        = 7168;//num of 128 bit
unsigned int    cfg_cim_in_num         = 128;//num of 128 bit
unsigned int    cfg_cim_out_num        = 64;//num of 128 bit
unsigned int    cfg_cim_relu_enable    = 0;
unsigned int    cim_shift_num          = 15;     
unsigned int    cim_in_num             = 4;

int main(void)
{
    printf("test");
    
    int i;
    unsigned int inst_buffer[1000];
    unsigned int inst127_96;
    unsigned int inst95_64;
    unsigned int inst63_32;
    unsigned int inst31_0;
    int  inst_num = 0;
    //inst for parameter
    inst31_0    = (cfg_cim_relu_enable<<16) | (cim_shift_num<<8) | cim_in_num ;
    inst63_32   = 0;
    inst95_64   = 0;
    inst127_96  = 0;
    inst_buffer[inst_num] = inst31_0;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst63_32;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst95_64;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst127_96;
    inst_num = inst_num + 1;

    //inst for mem_wet
    int reverved_transfer_num, transfer_num;
    unsigned long long int  axi_saddr;
    unsigned int sram_saddr;
    axi_saddr = BASE_DRAM1_ADDR;
    sram_saddr = 1<<19;
    reverved_transfer_num = cfg_cim_wet_num;
    while (reverved_transfer_num > 0){
        if(reverved_transfer_num > 256){
            transfer_num = 256;
        } else {
            transfer_num = reverved_transfer_num;
        }
        inst31_0   =  (( axi_saddr & 0x1FFFF )<< 15)| transfer_num; //{axi_saddr[16:0] , cfg_transfer_num[14:0]}
        inst63_32  = ((sram_saddr & 0x1FF)<<23) | (axi_saddr>>17); //{sram_saddr[8:0],axi_saddr[39:17] 23}
        inst95_64  = (1<<11) |  (sram_saddr>>9) ;//{sram_saddr[19:9]}
        inst127_96 = 1<<28;
        inst_buffer[inst_num] = inst31_0;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst63_32;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst95_64;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst127_96;
        inst_num = inst_num + 1;  
        reverved_transfer_num = reverved_transfer_num - 256;
        axi_saddr = axi_saddr + 0x1000;
        sram_saddr = sram_saddr + 0x100;
    }

    //inst for mem_act
    axi_saddr = BASE_DRAM0_ADDR;
    sram_saddr = 0;
    reverved_transfer_num = cfg_cim_in_num;
    while (reverved_transfer_num > 0){
        if(reverved_transfer_num > 256){
            transfer_num = 256;
        } else {
            transfer_num = reverved_transfer_num;
        }
        inst31_0   =  (( axi_saddr & 0x1FFFF )<< 15)| transfer_num; //{axi_saddr[16:0] , cfg_transfer_num[14:0]}
        inst63_32  = ((sram_saddr & 0x1FF)<<23) | (axi_saddr>>17); //{sram_saddr[8:0],axi_saddr[39:17] 23}
        inst95_64  = (1<<11) |  (sram_saddr>>9) ;//{sram_saddr[19:9]}
        inst127_96 = 2<<28;
        inst_buffer[inst_num] = inst31_0;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst63_32;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst95_64;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst127_96;
        inst_num = inst_num + 1;  
        reverved_transfer_num = reverved_transfer_num - 256;
        axi_saddr = axi_saddr + 0x1000;
        sram_saddr = sram_saddr + 0x100;
    }

    //inst_cim
        inst31_0   = 0;
        inst63_32  = 0;
        inst95_64  = 0;
        inst127_96 = 3<<28;
        inst_buffer[inst_num] = inst31_0;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst63_32;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst95_64;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst127_96;
        inst_num = inst_num + 1;  

     //inst_mem_out

    sram_saddr = 1<<18; 
    axi_saddr = BASE_DRAM0_ADDR + 0x0000001000 ;
    reverved_transfer_num = cfg_cim_out_num;
    while (reverved_transfer_num > 0){
        if(reverved_transfer_num > 256){
            transfer_num = 256;
        } else {
            transfer_num = reverved_transfer_num;
        }
        inst31_0 =  (( axi_saddr & 0x1FFFF )<< 15)| transfer_num; //{axi_saddr[16:0] , cfg_transfer_num[14:0]}
        inst63_32 = ((sram_saddr & 0x1FF)<<23) | (axi_saddr>>17); //{sram_saddr[8:0],axi_saddr[39:17] 23}
        inst95_64 = (0<<11) |  (sram_saddr>>9) ;//{sram_saddr[19:9]}
        inst127_96 = 2<<28;
        inst_buffer[inst_num] = inst31_0;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst63_32;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst95_64;
        inst_num = inst_num + 1;
        inst_buffer[inst_num] = inst127_96;
        inst_num = inst_num + 1;  
        sram_saddr = sram_saddr + 0x100;
        axi_saddr = axi_saddr + 0x1000;
        reverved_transfer_num = reverved_transfer_num - 256;
    }
    // inst for finish
    inst31_0 = 0;
    inst63_32 = 0;
    inst95_64 = 0;
    inst127_96 = 4<<28;
    inst_buffer[inst_num] = inst31_0;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst63_32;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst95_64;
    inst_num = inst_num + 1;
    inst_buffer[inst_num] = inst127_96;
    inst_num = inst_num + 1;  

    FILE *fp;
    
    fp=fopen("./instruction.h","w");
    fprintf(fp, "int inst[] = {\n");
    for(i = 0; i < inst_num; i++){
        if( i== inst_num - 1)
            fprintf(fp, "0x%08x };\n", inst_buffer[i]);
        else
            fprintf(fp, "0x%08x ,\n", inst_buffer[i]);
    }    
    fclose(fp);

    return 0;
    
}


















 